package com.wltjack.common;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 日志切面
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

    // 横切关注点
    @Pointcut("execution(public * com.wltjack.controller..*.*(..))")
    public void logPointCut() {
    }

    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录 请求信息
        log.info("requestUrl = {}", request.getRequestURL().toString());
        log.info("http method = {}", request.getMethod());
        log.info("client IP = {}", request.getRemoteAddr());
        log.info("Class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("参数：" + Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "ret", pointcut = "logPointCut()") // returning的值要和doAfterReturning方法的参数名一致
    public void doAfterReturning(Object ret) {
        // 方法执行完成，返回的时候
        log.info("returning value = " + ret);
    }

    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object proceedObj = pjp.proceed(); // 方法的返回值
        log.info("total times:" + (System.currentTimeMillis() - startTime));
        return proceedObj;
    }


}
